#include <cstdio>
#include <cstring>

const int N = 305;
int n;
int e_cnt, heads[N], dis[N];
bool vis[N];

struct Edge {
  int v, nxt, w;
} e[N * N];

inline void add(int u, int v, int w) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt, e[e_cnt].w = w;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#endif
#ifndef LOCAL
  freopen("Prim.in", "r", stdin);
  freopen("Prim.out", "w", stdout);
#endif
#endif

  scanf("%d", &n);
  for (int i = 1, w; i <= n; ++i) {
    scanf("%d", &w);
    add(0, i, w), add(i, 0, w);
  }
  for (int i = 1, w; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      scanf("%d", &w);
      if (i != j && i < j) {
        add(i, j, w), add(j, i, w);
      }
    }
  }
  int ans = 0;
  memset(dis, 0x7f, sizeof(dis));
  dis[0] = 0;
  for (int i = 0; i <= n; ++i) {
    int cur = n + 1;
    for (int j = 0; j <= n; ++j) {
      if (!vis[j] && dis[cur] > dis[j]) cur = j;
    }
    ans += dis[cur];
    vis[cur] = true;
    for (int j = heads[cur], v; j; j = e[j].nxt) {
      if (!vis[v = e[j].v] && dis[v] > e[j].w) dis[v] = e[j].w;
    }
  }
  printf("%d", ans);
  return 0;
}